package com.txzt.gaea.business.plan.controller;

import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.aspect.annotation.SysDataPermission;
import com.txzt.gaea.business.plan.domain.model.PlanIssue;
import com.txzt.gaea.business.plan.service.IPlanIssueService;
import com.txzt.gaea.business.util.TranslateUtil;
import com.txzt.gaea.common.annotation.EntityCommonValue;
import com.txzt.gaea.common.base.controller.BaseController;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.IsDeleteEnum;
import com.txzt.gaea.common.enums.IssueStatus;
import com.txzt.gaea.upgrade.out.domain.model.OutCoop;
import com.txzt.gaea.upgrade.out.service.IOutCoopService;
import com.txzt.gaea.vo.AdminUserVO;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.beetl.sql.core.engine.PageQuery;
import org.jeecgframework.poi.word.WordExportUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/plan/issue")
public class PlanIssueController extends BaseController {


    @Autowired
    private IPlanIssueService planIssueService;
    @Autowired
    private IOutCoopService outCoopService;

    /**
     * 分页查询
     *
     * @param pageNumber
     * @param pageSize
     * @param planIssue
     * @return
     */
    @SysDataPermission
    @GetMapping(value = "/list")
    public RtnInfo<?> pageList(@RequestParam(defaultValue = "1") Integer pageNumber,
                               @RequestParam(defaultValue = "10") Integer pageSize, PlanIssue planIssue) {
        PageQuery<PlanIssue> pageList = planIssueService.pageQuery(new PageQuery<>(pageNumber, pageSize, planIssue));
        return RtnInfo.success(translate(pageList));
    }

    private PageQuery<PlanIssue> translate(PageQuery<PlanIssue> pageList) {
        pageList.getList().forEach(item -> {
            //翻译提报人
            item.setCreateName(TranslateUtil.getUserName(item.getCreateBy()));
            //翻译负责人
            if (null != item.getProjectLeader()) {
                item.setProjectLeaderName(TranslateUtil.getUserName(item.getProjectLeader()));
            }
            //翻译承担部门
            item.setDepartName(TranslateUtil.getDepartmentName(item.getDepartId()));
            //翻译提报部门
            item.setDeptName(TranslateUtil.getDepartmentName(item.getDeptId()));
        });
        return pageList;
    }


    /**
     * 新增
     *
     * @param planIssue
     * @return
     */
    @PostMapping(value = "/add")
    @EntityCommonValue(operation = "CREATE")
    public RtnInfo<?> add(@RequestBody PlanIssue planIssue) {
        planIssue.setPlanStatus(IssueStatus.TODO.getCode());
        int count = planIssueService.insertTemplate(planIssue);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 更新
     *
     * @param planIssue
     * @return
     */
    @PutMapping(value = "/edit")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> editOnly(@RequestBody PlanIssue planIssue) {
        //校验编号去重
        List<PlanIssue> queryList= planIssueService.selectByNo(planIssue);
        if (!CollectionUtils.isEmpty(queryList)){
            return RtnInfo.error(RtnInfo.SERVER_ERROR.getCode(),"修改失败，有相同的项目编号已存在！");
        }
        int count = planIssueService.updateById(planIssue);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete")
    public RtnInfo<?> delete(@RequestParam Long id) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        PlanIssue planIssue = new PlanIssue();
        planIssue.setId(id);
        planIssue.setIsDelete(IsDeleteEnum.DELETE.getCode());
        planIssue.setUpdateBy(adminUserVO.getId());
        planIssue.setUpdateTime(new Date());
        int count = planIssueService.updateById(planIssue);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }


    /**
     * 计划下发 - 负责人，承担部门补全
     *
     * @param departId
     * @param projectLeader
     * @return
     */
    @GetMapping(value = "/assign")
    public RtnInfo<?> assignAndCompletion(@RequestParam Integer pageNumber, @RequestParam Integer pageSize
            , @RequestParam(required = false) Long departId, @RequestParam(required = false) Long projectLeader,
                                          @RequestParam(required = false) String ids) {
        boolean flag = planIssueService.assignAndCompletion(pageNumber, pageSize, departId, projectLeader, ids);
        if (flag) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }


    /**
     * 导入模板下载
     */
    @GetMapping(value = "/template")
    public RtnInfo<?> template(HttpServletResponse response) {
        return RtnInfo.success("");
    }

    private static int getSysYear() {
        Calendar date = Calendar.getInstance();
        return date.get(Calendar.YEAR);
    }

    @PostMapping(value = "/import")
    public RtnInfo<?> importWord(HttpServletRequest request){
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
        MultipartFile file = multipartRequest.getFile("file");
        if (null == file) {
            return RtnInfo.SUCCESS;
        }
        String planType = multipartRequest.getParameter("planType");
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        int sYear = getSysYear() - 5;
        int eYear = getSysYear() + 10;
        try {
            XWPFDocument xwpf = new XWPFDocument(file.getInputStream());
            List<XWPFTable> tableList = xwpf.getTables();
            AtomicInteger count = new AtomicInteger(0);
            if (tableList.size() > 0) {
                XWPFTable table = tableList.get(0);
                for (XWPFTableRow row : table.getRows()) {
                    if (count.get() > 0) {
                        if (StringUtils.isEmpty(row.getCell(0).getText())) {
                            return RtnInfo.error(99,"计划编号未填写不可导入！");
                        }else {
                            PlanIssue target = new PlanIssue();
                            target.setPlanNo(row.getCell(0).getText());
                            target.setIsDelete(IsDeleteEnum.NOTDELETE.getCode());
                            PlanIssue res = planIssueService.selectOne(target);
                            if (null != res){
                                return RtnInfo.error(99,"该计划编号已存在，请检查计划编号为 "+ res.getPlanNo() +" 的数据");
                            }
                        }
                        if (StringUtils.isEmpty(row.getCell(1).getText())) {
                            return RtnInfo.error(99,"项目名称未填写不可导入！");
                        }
                        if (StringUtils.isEmpty(row.getCell(2).getText())) {
                            return RtnInfo.error(99,"计划子类未填写不可导入！");
                        }else {
                            if (StringUtils.isEmpty(TranslateUtil.getPlanType(planType,row.getCell(2).getText()))){
                                return RtnInfo.error(99,"未找到对应计划子类信息，请检查！");
                            }
                        }
                        if (StringUtils.isEmpty(row.getCell(5).getText())) {
                            return RtnInfo.error(99,"计划开始年度未填写不可导入！");
                        }else{
                            if (sYear > Integer.parseInt(row.getCell(5).getText()) || eYear < Integer.parseInt(row.getCell(5).getText())){
                                return RtnInfo.error(99,"计划开始年度范围必须在"+ sYear + "-" + eYear + "之间");
                            }
                        }
                        if (StringUtils.isEmpty(row.getCell(6).getText())) {
                            return RtnInfo.error(99,"计划结束年度未填写不可导入！");
                        }else {
                            if (sYear > Integer.parseInt(row.getCell(6).getText()) || eYear < Integer.parseInt(row.getCell(6).getText())){
                                return RtnInfo.error(99,"计划结束年度范围必须在"+ sYear + "-" + eYear + "之间");
                            }
                        }
                        if(Integer.parseInt(row.getCell(5).getText()) > Integer.parseInt(row.getCell(6).getText())){
                            return RtnInfo.error(99,"计划开始年度不得大于计划结束年度！");
                        }
                        if (StringUtils.isEmpty(row.getCell(7).getText())) {
                            return RtnInfo.error(99,"研制周期未填写不可导入！");
                        }else if (Integer.parseInt(row.getCell(7).getText()) != (Integer.parseInt(row.getCell(6).getText()) - Integer.parseInt(row.getCell(5).getText()) + 1)){
                            return RtnInfo.error(99,"研制周期必须等于计划结束年度与计划开始年度之差！");
                        }
                        PlanIssue planIssue = new PlanIssue();
                        planIssue.setPlanStatus(IssueStatus.TODO.getCode());
                        planIssue.setPlanNo(row.getCell(0).getText());
                        planIssue.setProjectName(row.getCell(1).getText());
                        planIssue.setPlanType(planType);
                        planIssue.setSubType(TranslateUtil.getPlanType(planType,row.getCell(2).getText()));
                        planIssue.setResearchContent(row.getCell(3).getText());
                        planIssue.setDepartId(TranslateUtil.getDepartmentId(row.getCell(4).getText()));
                        planIssue.setStartYear(Integer.valueOf(row.getCell(5).getText()));
                        planIssue.setEndYear(Integer.valueOf(row.getCell(6).getText()));
                        planIssue.setLeadTime(Integer.valueOf(row.getCell(7).getText()));
                        planIssue.setResultForm(row.getCell(8).getText());
                        if (!StringUtils.isEmpty(row.getCell(9).getText())) {
                            planIssue.setBudgetFund(BigDecimal.valueOf(Double.parseDouble(row.getCell(9).getText())));
                        }
                        if (!StringUtils.isEmpty(row.getCell(10).getText())) {
                            planIssue.setArrangeFund(BigDecimal.valueOf(Double.parseDouble(row.getCell(10).getText())));
                        }
                        if (!StringUtils.isEmpty(row.getCell(11).getText())) {
                            planIssue.setYearFund(BigDecimal.valueOf(Double.parseDouble(row.getCell(11).getText())));
                        }
                        if (!StringUtils.isEmpty(row.getCell(12).getText())) {
                            planIssue.setNextFund(BigDecimal.valueOf(Double.parseDouble(row.getCell(12).getText())));
                        }
                        planIssue.setTaskSource(row.getCell(13).getText());
                        planIssue.setTaskSourceExplain(row.getCell(14).getText());
                        planIssue.setRemark(row.getCell(15).getText());
                        planIssue.setDeptId(adminUserVO.getDeptid());
                        planIssue.setCreateBy(adminUserVO.getId());
                        planIssue.setCreateTime(new Date());
                        planIssueService.save(planIssue);
                    }
                    count.addAndGet(1);
                }
            }else{
                return RtnInfo.error(RtnInfo.SERVER_ERROR.getCode(),"导入失败，请确认导入文件正确！");
            }
        } catch (Exception e) {
            System.out.println(e.toString());
            return RtnInfo.error(RtnInfo.SERVER_ERROR.getCode(),"导入失败，请确认导入文件正确！");
        }
        return RtnInfo.SUCCESS;
    }


    @Value("${template.taskReport}")
    String taskReportPath;

    @GetMapping(value = "/export")
    public void exportWord(Long id, HttpServletResponse response) throws Exception {
        PlanIssue planIssue = planIssueService.selectById(id);
        OutCoop coop = new OutCoop();
        coop.setId(id);
        OutCoop outCoop = outCoopService.queryOrgAdvice(coop);
        Map<String, Object> map = new HashMap<String, Object>(12);
        //计划编号
        map.put("planNo", planIssue.getPlanNo());
        //项目名称
        map.put("projectName", planIssue.getProjectName());
        //项目组长
        map.put("projectLeaderName", TranslateUtil.getUserName(planIssue.getProjectLeader()));
        //任务来源
        if (StringUtils.isEmpty(planIssue.getTaskSource())) {
            map.put("taskSource", " ");
        }else {
            map.put("taskSource", planIssue.getTaskSource());
        }
        //主要研究内容及要求
        if (StringUtils.isEmpty(planIssue.getResearchContent())) {
            map.put("searchContent", " ");
        }else {
            map.put("searchContent", planIssue.getResearchContent());
        }
        //开始年度
        if (null == planIssue.getStartYear()) {
            map.put("startYear", " ");
        }else {
            map.put("startYear", planIssue.getStartYear());
        }
        //结束年度
        if (null == planIssue.getEndYear()) {
            map.put("endYear", " ");
        }else {
            map.put("endYear", planIssue.getEndYear());
        }
        //研制周期
        if (null == planIssue.getLeadTime()) {
            map.put("leadTime", " ");
        }else {
            map.put("leadTime", planIssue.getLeadTime());
        }
        //成果形式
        if (StringUtils.isEmpty(planIssue.getResultForm())) {
            map.put("resultForm", " ");
        }else {
            map.put("resultForm", planIssue.getResultForm());
        }
        //协作单位
        if (StringUtils.isEmpty(outCoop.getOrgAdvice())) {
            map.put("orgAdvice", " ");
        }else {
            map.put("orgAdvice", outCoop.getOrgAdvice());
        }
        //经费预算
        if (null == planIssue.getBudgetFund()) {
            map.put("budgetFund", " ");
        }else {
            map.put("budgetFund", planIssue.getBudgetFund());
        }
        if (StringUtils.isEmpty(planIssue.getRemark())) {
            map.put("remark", " ");
        }else {
            map.put("remark", planIssue.getRemark());
        }
        XWPFDocument doc = WordExportUtil.exportWord07(taskReportPath, map);
        //输出文件流
        OutputStream outputStream;
        outputStream = new BufferedOutputStream(response.getOutputStream());
        doc.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }
}
